package com.itheima.pinda.common.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.text.DecimalFormat;
import java.util.Map;

/**
 * 百度地图操作工具类
 * <p>
 * 第一步: 调用百度地图提供的地理编码接口. 根据订单中寄件人地址和收件人地址分别获取经纬度
 * 第二步: 调用百度地图提供的驾车路线规划接口. 根据第一步获取的寄件人经纬度和收件人地址经纬度来获取订单距离等信息
 *
 * @author llhuang10
 * @date 2021/10/9 22:59
 */
@Slf4j
public class BaiduMapUtil {

    /**
     * 后期将这个AK的值, 抽取到配置文件中, 然后使用工具类获取SpringContext上下文对象为这个AK对象初始化
     */
    private final static String AK = "QcSZG1qZStxXKGs0MdGL6g2My9zKogA2";


    /**
     * 调用百度地图驾车路线规范服务接口, 根据寄件人地址和收件人地址坐标计算线路耗时
     *
     * @param origin      寄件人地址
     * @param destination 收件人地址
     * @return 线路耗时, 单位: 秒
     */
    public static Integer getTime(String origin, String destination) {
        if (StringUtils.isBlank(origin) || StringUtils.isBlank(destination)) {
            log.error("寄件人地址或收件人地址为空!!!, org: {}, dest:{}", origin, destination);
            return null;
        }
        // 返回值格式类型,   纬度,经度
        String orgCoordinate = getCoordinate(origin);
        String destCoordinate = getCoordinate(destination);
        if (StringUtils.isBlank(orgCoordinate) || StringUtils.isBlank(destCoordinate)) {
            log.error("寄件人地址或收件人地址解析的经纬度为空!!!, org: {}, dest: {}", orgCoordinate, destCoordinate);
            return null;
        }

        String httpUrl = "http://api.map.baidu.com/directionlite/v1/driving?origin=" +
                orgCoordinate + "&destination=" + destCoordinate + "&ak=" + AK;
        String response = HttpRequestUtil.get(httpUrl);
        // 解析结果数据
        if (StringUtils.isNotBlank(response)) {
            Map map = JSONObject.parseObject(response, Map.class);
            if ("0".equals(map.getOrDefault("status", "500").toString())) {
                Map childMap = (Map) map.get("result");
                // 这里的返回值routes的数据格式为routes: [{"distance": 83040,"duration": 5157}, {"distance": 94561,"duration":6520}]
                JSONArray jsonArray = (JSONArray) childMap.get("routes");
                JSONObject route = (JSONObject) jsonArray.get(0);

                // 方案耗时
                return Integer.parseInt(route.get("duration") == null ? "0" : route.get("duration").toString());
            }
        }
        return null;
    }

    /**
     * 调用百度地图地理编码服务接口, 根据地址获取坐标(经度, 纬度)
     *
     * @param address 地址
     * @return 坐标(纬度, 经度)
     */
    public static String getCoordinate(String address) {
        if (StringUtils.isNotBlank(address)) {
            address = address.replaceAll("\\s*", "").replace("#", "栋");
            String url = "https://api.map.baidu.com/geocoding/v3/?address=" +
                    address + "&output=json&ak=" + AK;

            String response = HttpRequestUtil.get(url);
            // 解析结果数据
            if (StringUtils.isNotBlank(response)) {
                Map map = JSONObject.parseObject(response, Map.class);
                if ("0".equals(map.getOrDefault("status", "500").toString())) {
                    Map childMap = (Map) map.get("result");
                    Map posMap = (Map) childMap.get("location");
                    // 经度
                    double lng = Double.parseDouble(posMap.getOrDefault("lng", "0").toString());
                    // 纬度
                    double lat = Double.parseDouble(posMap.getOrDefault("lat", "0").toString());
                    DecimalFormat df = new DecimalFormat("#.######");
                    String lngStr = df.format(lng);
                    String latStr = df.format(lat);
                    return latStr + "," + lngStr;
                }
            }
        }

        return null;
    }

    /**
     * 调用百度地图驾车路线规范服务接口, 根据寄件人地址和收件人地址坐标计算订单距离
     *
     * @param origin      寄件人地址
     * @param destination 收件人地址
     * @return 寄件人 -> 收件人的距离
     */
    public static Double getDistance(String origin, String destination) {
        if (StringUtils.isBlank(origin) || StringUtils.isBlank(destination)) {
            log.error("寄件人地址或收件人地址为空!!!, org: {}, dest:{}", origin, destination);
            return null;
        }
        // 返回值格式类型,   纬度,经度
        String orgCoordinate = getCoordinate(origin);
        String destCoordinate = getCoordinate(destination);
        if (StringUtils.isBlank(orgCoordinate) || StringUtils.isBlank(destCoordinate)) {
            log.error("寄件人地址或收件人地址解析的经纬度为空!!!, org: {}, dest: {}", orgCoordinate, destCoordinate);
            return null;
        }

        String httpUrl = "http://api.map.baidu.com/directionlite/v1/driving?origin=" +
                orgCoordinate + "&destination=" + destCoordinate + "&ak=" + AK;
        String response = HttpRequestUtil.get(httpUrl);
        // 解析结果数据
        if (StringUtils.isNotBlank(response)) {
            Map map = JSONObject.parseObject(response, Map.class);
            if ("0".equals(map.getOrDefault("status", "500").toString())) {
                Map childMap = (Map) map.get("result");
                JSONArray jsonArray = (JSONArray) childMap.get("routes");
                JSONObject route = (JSONObject) jsonArray.get(0);

                // 方案距离
                return Double.parseDouble(route.get("distance") == null ? "0" : route.get("distance").toString());
            }
        }
        return null;
    }

}
